<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>小鸡炖蘑菇</title>
<style type="text/css">
	* { color:#000; }
	body { background:#efefef;font-size:16px; }
	h1 { text-align:center; }
	p { line-height:30px;text-indent:30px; }
	.st { color:#f00;font-weight:bold; }
	pre { background:#eee;border:2px solid #3034eb;color:#444;font-size:larger;font-family:Arial;padding:10px; }
</style>
 </head>
 <body>
  <h1>小鸡炖蘑菇hehe</h1>
	<h2>匿名函数</h2>
	<p>函数是一组可以随时随地运行的语句。</p>
	<p>匿名函数就是没有名字的函数，又叫拉姆达（lambda）函数。</p>
	<p>创建函数</p>
	<pre>
	function fnOne() {//具有名称的函数,函数名必须符合变量名命名规范
		//可以没有任何语句
	}
	var fnTwo = function () {//匿名函数
	};
	function () {//创建匿名函数而不立即创建其引用，那么之后就没办法调用此函数
	}
	(function fnThree() {
	})();//创建函数并立即执行一次
	(function () {})();//创建匿名函数并立即执行一次</pre>
	<p>匿名函数与命名函数的区别</p>
	<pre>
	fnOne();//不会出错，使用function创建的具有名称的函数在任何与之相同作用域的地方都能调用
	fnTwo();//出错
	var fnTwo =function () {};//因为只有执行了这个赋值语句后，fnTwo才会被创建
	function fnOne() {}</pre>
	<p>函数返回值</p>
	<pre>
	function fnTest() {
		return "value";//使用return来返回值
		alert("Hello!!!");//执行了return之后，函数就会退出 
	}</pre>
	<p>函数参数</p>
	<pre>
	function fnTest(arg1,arg2,arg3) {
		alert(arg1+"\n"+arg2+"\n"+arg3);
	}
	fnTest(1,2,3);
	fnTest(1,2);//没有传值过去时，就会是undefined</pre>
	<p>arguments对象:在函数执行时函数内部就会有arguments对象，它包含了所有的参数，arguments的length属性报告了传入参数个数</p>
	<pre>
	function fnTest() {
		for (var i=0;i< arguments.length;i++) {
			alert(arguments[i]);
		}
	}
	fnTest(1,2,3);
	fnTest(45);</pre>
	
	<p>arguments对象补充:arguments对象的callee属性指向它所在的函数</p>
	<pre>
	function fnTest() {alert(arguments.callee);}</pre>

	<p class="st">注意：匿名函数的执行环境具有全局性！如果想访问作用域中的this和arguments对象，必须将该对象的引用保存到另一个闭包能够访问的变量中！</p>
	<h2>闭包</h2>
	<p>定义:是指有权访问另一个函数作用域中的变量的函数。</p>
	<p>闭包，也就是函数可以使用函数之外定义的变量。</p>
	<p>其实全局变量是一个简单的闭包：</p>
	<pre>
	var msg = "我是全局变量!!!";
	function say() {
	  alert(msg);
	}
	say();</pre>
	<p>在函数声明处向函数外部找到的声明的所有变量，在函数内部都能访问到它们的最终值 ！</p>
	<pre>
	var g = "全局变量！！！";
	function fnA() {
		var a="A";
		function fnB() {
			var b="B";
			alert(a);//可以访问到a
			alert(c);//但不以访问c
			function fnC() {
				var c = "C";
				alert(a+"\n"+b);//只要遵循从里向外看的原则，看到的变量都可以访问到
			}
		}
	}
	//更复杂的闭包
	function fnTest(num1,num2) {
		var num3 = num1+num2;
		return function () {
			alert("num1+num2结果为"+num3);
		};
	}
	var result = fnTest(23,56);
	result();</pre>
	<p>闭包函数只能访问变量的最终值!!!</p>
	<pre>
	function fnTest(arr) {
		for (var i=0;i < arr.length;i++) {
			arr[i]=function () {
				alert(i+" | "+arr[i]);
			};
		}
	}
	var arr = [0,1,2,3,4,5];
	fnTest(arr);
	for (var i=0;i < arr.length;i++) {
		arr[i]();//始终输出6还有一个undefined
		//因为函数退出后，i值为6,所以访问到的值只有6
	}</pre>
	<p>不但在闭包中可以访问闭包外的变量值，而且还可以设置它的值</p>
	<pre>
	function fnTest() {
		var a=123;
		return {
			set:function (param) {a = param},
			get:function () {return a}
		};
	}
	var obj = fnTest();
	alert(obj.get());//123
	obj.set(4);
	alert(obj.get());//4</pre>

	<p class="st">注意：由于闭包会携带包含它的函数的作用域，因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多，建议同学们只在绝对必要时再考虑使用闭包。能不用，就不用！</p>
 </body>
</html>
